"""
任务服务模块
提供任务管理的业务逻辑处理
"""

from typing import List, Optional, Dict, Any, Tuple
from datetime import datetime, timedelta, date
from models.task import Task
from models.task_dao import TaskDAO
from models.database import DatabaseManager
from models.query_builder import create_task_filter, TaskQueryBuilder


class TaskService:
    """任务服务类"""
    
    def __init__(self, db_manager: Optional[DatabaseManager] = None):
        """
        初始化任务服务
        
        Args:
            db_manager: 数据库管理器实例
        """
        self.task_dao = TaskDAO(db_manager)
    
    def add_task(self, title: str, description: Optional[str] = None,
                 priority: str = 'medium', category: Optional[str] = None,
                 due_date: Optional[str] = None) -> Tuple[bool, str, Optional[Task]]:
        """
        添加新任务
        
        Args:
            title: 任务标题
            description: 任务描述
            priority: 优先级
            category: 分类
            due_date: 截止日期
            
        Returns:
            (是否成功, 消息, 任务对象)
        """
        try:
            # 创建任务对象（会自动进行数据验证）
            task = Task(
                title=title,
                description=description,
                priority=priority,
                category=category,
                due_date=due_date
            )
            
            # 保存到数据库
            task_id = self.task_dao.create(task)
            
            return True, f"任务创建成功，ID: {task_id}", task
            
        except ValueError as e:
            return False, f"数据验证失败: {str(e)}", None
        except Exception as e:
            return False, f"创建任务失败: {str(e)}", None
    
    def get_task(self, task_id: int) -> Optional[Task]:
        """
        获取指定任务
        
        Args:
            task_id: 任务 ID
            
        Returns:
            任务对象或 None
        """
        return self.task_dao.get_by_id(task_id)
    
    def edit_task(self, task_id: int, **updates) -> Tuple[bool, str]:
        """
        编辑任务
        
        Args:
            task_id: 任务 ID
            **updates: 要更新的字段
            
        Returns:
            (是否成功, 消息)
        """
        try:
            # 获取现有任务
            task = self.task_dao.get_by_id(task_id)
            if not task:
                return False, f"任务 {task_id} 不存在"
            
            # 更新任务属性（会自动进行数据验证）
            task.update(**updates)
            
            # 保存更新
            if self.task_dao.update(task):
                return True, "任务更新成功"
            else:
                return False, "任务更新失败"
                
        except ValueError as e:
            return False, f"数据验证失败: {str(e)}"
        except Exception as e:
            return False, f"编辑任务失败: {str(e)}"
    
    def delete_task(self, task_id: int) -> Tuple[bool, str]:
        """
        删除任务
        
        Args:
            task_id: 任务 ID
            
        Returns:
            (是否成功, 消息)
        """
        try:
            # 检查任务是否存在
            task = self.task_dao.get_by_id(task_id)
            if not task:
                return False, f"任务 {task_id} 不存在"
            
            # 删除任务
            if self.task_dao.delete(task_id):
                return True, f"任务 '{task.title}' 删除成功"
            else:
                return False, "删除任务失败"
                
        except Exception as e:
            return False, f"删除任务失败: {str(e)}"
    
    def complete_task(self, task_id: int) -> Tuple[bool, str]:
        """
        标记任务为已完成
        
        Args:
            task_id: 任务 ID
            
        Returns:
            (是否成功, 消息)
        """
        return self.edit_task(task_id, status='completed')
    
    def start_task(self, task_id: int) -> Tuple[bool, str]:
        """
        开始任务（标记为进行中）
        
        Args:
            task_id: 任务 ID
            
        Returns:
            (是否成功, 消息)
        """
        return self.edit_task(task_id, status='in_progress')
    
    def reopen_task(self, task_id: int) -> Tuple[bool, str]:
        """
        重新打开任务（标记为待办）
        
        Args:
            task_id: 任务 ID
            
        Returns:
            (是否成功, 消息)
        """
        return self.edit_task(task_id, status='todo')
    
    def list_tasks(self, status: Optional[str] = None,
                   priority: Optional[str] = None,
                   category: Optional[str] = None,
                   sort_by: str = 'created_at',
                   reverse: bool = False) -> List[Task]:
        """
        获取任务列表
        
        Args:
            status: 状态过滤
            priority: 优先级过滤
            category: 分类过滤
            sort_by: 排序字段
            reverse: 是否倒序
            
        Returns:
            任务列表
        """
        try:
            # 构建过滤条件
            filters = {}
            if status:
                filters['status'] = status
            if priority:
                filters['priority'] = priority
            if category:
                filters['category'] = category
            
            # 获取任务列表
            tasks = self.task_dao.get_all(filters)
            
            # 排序
            if sort_by == 'priority':
                tasks.sort(key=lambda t: t.get_priority_weight(), reverse=not reverse)
            elif sort_by == 'due_date':
                tasks.sort(key=lambda t: t.due_date or '9999-12-31', reverse=reverse)
            elif sort_by == 'title':
                tasks.sort(key=lambda t: t.title.lower(), reverse=reverse)
            else:  # 默认按创建时间排序
                tasks.sort(key=lambda t: t.created_at, reverse=not reverse)
            
            return tasks
            
        except Exception as e:
            print(f"获取任务列表失败: {str(e)}")
            return []
    
    def search_tasks(self, keyword: str, search_fields: List[str] = None) -> List[Task]:
        """
        搜索任务
        
        Args:
            keyword: 搜索关键词
            search_fields: 搜索字段列表
            
        Returns:
            匹配的任务列表
        """
        if not keyword.strip():
            return []
        
        try:
            # 使用高级查询构建器
            query = TaskQueryBuilder()
            query.search_text(keyword.strip(), search_fields or ['title', 'description'])
            query.sort_by('created_at', 'DESC')
            
            sql, params = query.build()
            rows = self.task_dao.db.execute_query(sql, params)
            
            return [Task.from_db_row(row) for row in rows]
            
        except Exception as e:
            print(f"搜索任务失败: {str(e)}")
            return []
    
    def advanced_search(self, filters: Dict[str, Any]) -> List[Task]:
        """
        高级搜索任务
        
        Args:
            filters: 过滤条件字典
            
        Returns:
            匹配的任务列表
        """
        try:
            query = create_task_filter(filters)
            sql, params = query.build()
            
            rows = self.task_dao.db.execute_query(sql, params)
            return [Task.from_db_row(row) for row in rows]
            
        except Exception as e:
            print(f"高级搜索失败: {str(e)}")
            return []
    
    def filter_tasks_by_date_range(self, start_date: Optional[str] = None, 
                                  end_date: Optional[str] = None) -> List[Task]:
        """
        按日期范围过滤任务
        
        Args:
            start_date: 开始日期
            end_date: 结束日期
            
        Returns:
            匹配的任务列表
        """
        filters = {}
        if start_date:
            filters['due_date_start'] = start_date
        if end_date:
            filters['due_date_end'] = end_date
        
        return self.advanced_search(filters)
    
    def get_tasks_by_multiple_criteria(self, statuses: List[str] = None,
                                     priorities: List[str] = None,
                                     categories: List[str] = None,
                                     keyword: str = None,
                                     sort_by: str = 'created_at',
                                     sort_direction: str = 'DESC',
                                     limit: int = None) -> List[Task]:
        """
        根据多个条件获取任务
        
        Args:
            statuses: 状态列表
            priorities: 优先级列表
            categories: 分类列表
            keyword: 搜索关键词
            sort_by: 排序字段
            sort_direction: 排序方向
            limit: 限制数量
            
        Returns:
            匹配的任务列表
        """
        filters = {
            'sort_by': sort_by,
            'sort_direction': sort_direction
        }
        
        if statuses:
            filters['status'] = statuses
        if priorities:
            filters['priority'] = priorities
        if categories:
            filters['category'] = categories
        if keyword:
            filters['search'] = keyword
        if limit:
            filters['limit'] = limit
        
        return self.advanced_search(filters)
    
    def get_tasks_with_pagination(self, page: int = 1, page_size: int = 20,
                                 filters: Dict[str, Any] = None) -> Tuple[List[Task], Dict[str, int]]:
        """
        分页获取任务
        
        Args:
            page: 页码（从1开始）
            page_size: 每页大小
            filters: 过滤条件
            
        Returns:
            (任务列表, 分页信息)
        """
        try:
            # 计算偏移量
            offset = (page - 1) * page_size
            
            # 构建过滤条件
            search_filters = filters.copy() if filters else {}
            search_filters.update({
                'limit': page_size,
                'offset': offset
            })
            
            # 获取任务列表
            tasks = self.advanced_search(search_filters)
            
            # 获取总数（不带分页限制）
            count_filters = filters.copy() if filters else {}
            if 'limit' in count_filters:
                del count_filters['limit']
            if 'offset' in count_filters:
                del count_filters['offset']
            
            total_tasks = self.advanced_search(count_filters)
            total_count = len(total_tasks)
            
            # 计算分页信息
            total_pages = (total_count + page_size - 1) // page_size
            has_next = page < total_pages
            has_prev = page > 1
            
            pagination_info = {
                'current_page': page,
                'page_size': page_size,
                'total_count': total_count,
                'total_pages': total_pages,
                'has_next': has_next,
                'has_prev': has_prev
            }
            
            return tasks, pagination_info
            
        except Exception as e:
            print(f"分页获取任务失败: {str(e)}")
            return [], {}
    
    def get_overdue_tasks(self) -> List[Task]:
        """
        获取过期任务
        
        Returns:
            过期任务列表
        """
        return self.task_dao.get_overdue_tasks()
    
    def get_upcoming_tasks(self, days: int = 7) -> List[Task]:
        """
        获取即将到期的任务
        
        Args:
            days: 未来天数
            
        Returns:
            即将到期的任务列表
        """
        return self.task_dao.get_upcoming_tasks(days)
    
    def get_today_tasks(self) -> List[Task]:
        """
        获取今天的任务
        
        Returns:
            今天的任务列表
        """
        today = datetime.now().date().isoformat()
        return self.get_upcoming_tasks(0)  # 今天到期的任务
    
    def get_task_statistics(self) -> Dict[str, Any]:
        """
        获取任务统计信息
        
        Returns:
            统计信息字典
        """
        try:
            stats = self.task_dao.get_statistics()
            
            # 计算完成率
            total = stats.get('total', 0)
            completed = stats.get('status_completed', 0)
            completion_rate = (completed / total * 100) if total > 0 else 0
            
            # 获取过期任务数量
            overdue_count = len(self.get_overdue_tasks())
            
            # 获取即将到期任务数量
            upcoming_count = len(self.get_upcoming_tasks())
            
            # 获取今天的任务数量
            today_count = len(self.get_today_tasks())
            
            return {
                'total': total,
                'todo': stats.get('status_todo', 0),
                'in_progress': stats.get('status_in_progress', 0),
                'completed': completed,
                'high_priority': stats.get('priority_high', 0),
                'medium_priority': stats.get('priority_medium', 0),
                'low_priority': stats.get('priority_low', 0),
                'completion_rate': round(completion_rate, 1),
                'overdue_count': overdue_count,
                'upcoming_count': upcoming_count,
                'today_count': today_count
            }
            
        except Exception as e:
            print(f"获取统计信息失败: {str(e)}")
            return {}
    
    def batch_complete_tasks(self, task_ids: List[int]) -> Tuple[int, int]:
        """
        批量完成任务
        
        Args:
            task_ids: 任务 ID 列表
            
        Returns:
            (成功数量, 失败数量)
        """
        success_count = self.task_dao.batch_update_status(task_ids, 'completed')
        failed_count = len(task_ids) - success_count
        return success_count, failed_count
    
    def clean_completed_tasks(self) -> int:
        """
        清理已完成的任务
        
        Returns:
            删除的任务数量
        """
        return self.task_dao.delete_completed_tasks()
    
    def validate_task_data(self, title: str, priority: str = 'medium',
                          status: str = 'todo', due_date: Optional[str] = None) -> Tuple[bool, str]:
        """
        验证任务数据
        
        Args:
            title: 任务标题
            priority: 优先级
            status: 状态
            due_date: 截止日期
            
        Returns:
            (是否有效, 错误消息)
        """
        try:
            # 尝试创建任务对象进行验证
            Task(title=title, priority=priority, status=status, due_date=due_date)
            return True, "数据验证通过"
            
        except ValueError as e:
            return False, str(e)
        except Exception as e:
            return False, f"验证失败: {str(e)}"
    
    def get_categories(self) -> List[str]:
        """
        获取所有任务分类
        
        Returns:
            分类列表
        """
        try:
            query = "SELECT DISTINCT category FROM tasks WHERE category IS NOT NULL ORDER BY category"
            rows = self.task_dao.db.execute_query(query)
            return [row['category'] for row in rows]
            
        except Exception as e:
            print(f"获取分类列表失败: {str(e)}")
            return []
    
    def export_tasks(self, format: str = 'json') -> Tuple[bool, str, Optional[str]]:
        """
        导出任务数据
        
        Args:
            format: 导出格式 ('json' 或 'csv')
            
        Returns:
            (是否成功, 消息, 导出数据)
        """
        try:
            tasks = self.list_tasks()
            
            if format.lower() == 'json':
                import json
                data = [task.to_dict() for task in tasks]
                export_data = json.dumps(data, ensure_ascii=False, indent=2)
                return True, f"成功导出 {len(tasks)} 个任务", export_data
                
            elif format.lower() == 'csv':
                import csv
                import io
                
                output = io.StringIO()
                writer = csv.writer(output)
                
                # 写入表头
                writer.writerow(['ID', '标题', '描述', '优先级', '状态', '分类', '截止日期', '创建时间'])
                
                # 写入数据
                for task in tasks:
                    writer.writerow([
                        task.id, task.title, task.description or '',
                        task.priority, task.status, task.category or '',
                        task.due_date or '', task.created_at
                    ])
                
                export_data = output.getvalue()
                output.close()
                
                return True, f"成功导出 {len(tasks)} 个任务", export_data
            
            else:
                return False, f"不支持的导出格式: {format}", None
                
        except Exception as e:
            return False, f"导出失败: {str(e)}", None